package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.api.ArticleClient;
import com.heima.common.exception.CustomException;
import com.heima.model.article.dto.ArticleDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.constant.WmNewsMessageConstants;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.WmThreadLocalUtil;
import com.heima.wemedia.mapper.NewsMapper;
import com.heima.wemedia.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.service.ApiListing;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @projectName: heima-leadnews
 * @package: com.heima.wemedia.service.impl
 * @className: NewsServiceImpl
 * @author: 躺着认真玩
 * @description: 文章内容模块
 * @date: 2025/5/19 8:04
 * @version: 1.0
 */
@Service
public class NewsServiceImpl extends ServiceImpl<NewsMapper, WmNews> implements NewsService {
    @Autowired
    private MaterialService materialService;
    @Autowired
    private MaterialNewService materialNewService;
    @Autowired
    private WmNewAuditService wmNewAuditService;

    /**
     * @param dto
     * 文章内容分页查询
     * @return
     */
    @Override
    public PageResponseResult findAll(WmNewsPageReqDto dto) {
        // 校验参数
        dto.checkParam();
        Integer id = WmThreadLocalUtil.getUser().getId();
        // 分页查询
        Page<WmNews> page = this.lambdaQuery()
                .like(dto.getKeyword() != null && dto.getKeyword() != "",WmNews::getTitle,dto.getKeyword())
                .gt(dto.getBeginPubDate() != null,WmNews::getPublishTime,dto.getBeginPubDate())
                .lt(dto.getEndPubDate() != null,WmNews::getPublishTime,dto.getEndPubDate())
                .eq(dto.getChannelId() != null,WmNews::getChannelId,dto.getChannelId())
                .eq(dto.getStatus() != null,WmNews::getStatus,dto.getStatus())
                .eq(WmNews::getUserId, id)
                .page(new Page<>(dto.getPage(), dto.getSize()));
        PageResponseResult pageResponseResult = new PageResponseResult((int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal());
        pageResponseResult.setData(page.getRecords());
        return pageResponseResult;
    }

    @Override
    @Transactional
    public void submit(WmNewsDto wmNewsDto)  {
        if (wmNewsDto == null || wmNewsDto.getContent() == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        WmNews wmNews = BeanUtil.copyProperties(wmNewsDto, WmNews.class);
        wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
        if (wmNewsDto.getImages() != null && !wmNewsDto.getImages().isEmpty()) {
            wmNews.setImages(StrUtil.join(",",wmNewsDto.getImages()));
        }
        // 封面图片为自动时
        if (wmNewsDto.getType() == (-1)) {
            wmNews = handImages(wmNews);
        }
        // 保存草稿
        if (wmNewsDto.getStatus() == 0) {
            if (wmNewsDto.getId() == null) {
            //     新增草稿
                wmNews.setCreatedTime(new Date());
                save(wmNews);
            }else {
                // 根据id修改草稿
                updateById(wmNews);
            }
        }

        // 提交审核(未审核)
        if (wmNewsDto.getStatus() == 1) {
            if (wmNewsDto.getId() == null) {
                //     新增
                wmNews.setCreatedTime(new Date());
                save(wmNews);
                // 新增素材文章关系表
                handRelation(wmNews,wmNewsDto);
            }else {
                // 根据id修改
                updateById(wmNews);
                // 删除关系表
                materialNewService.lambdaUpdate()
                        .eq(WmNewsMaterial::getNewsId,wmNews.getId())
                        .remove();
                // 新增关系表
                handRelation(wmNews,wmNewsDto);
            }
        }

        // 审核
        try {
            wmNewAuditService.autoAudit(wmNews);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        return;
    }

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 文章上下架
     *
     * @param wmNewsDto WM 新闻 DTO
     */
    @Override
    public void upOrDown(WmNewsDto wmNewsDto) throws CustomException {
        // 参数校验
        if (wmNewsDto == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 判断文章是否存在
        WmNews one = this.lambdaQuery().eq(WmNews::getId, wmNewsDto.getId())
                .one();
        if (one == null)throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        // 文章是否为以发布
        if (one.getStatus() != 9) {
            throw new CustomException(AppHttpCodeEnum.ARTICLESCANONLYBEREMOVEDORUNLISTEDA);
        }
        // 修改自媒体文章参数
        this.lambdaUpdate().eq(WmNews::getId, wmNewsDto.getId())
                .set(WmNews::getEnable,wmNewsDto.getEnable())
                .update();
        // kafka进行同步app端数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("articleId",one.getArticleId());
        if (wmNewsDto.getEnable() == 0) {
            map.put("enable",true);
        }else {
            map.put("enable",false);
        }
        if (one.getArticleId() != null) {
            kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JSONUtil.toJsonStr(map));
        }
        return;

    }

    /**
     * @param wmNews
     * @param wmNewsDto
     * 新增素材文章关系表
     */
    private void handRelation(WmNews wmNews, WmNewsDto wmNewsDto) {

        //     查看文章内容中图片
        List<Map> list = JSONUtil.toList(JSONUtil.parseArray(wmNews.getContent()), Map.class);
        List<String> result = new ArrayList<>();
        for (Map map : list) {
            if (map.get("type").toString().equals("image")) {
                String pickerUrl = map.get("value").toString();
                result.add(pickerUrl);
            }
        }
        if (!result.isEmpty()) {
        // 0 内容引用
            saveRelation((short)0,result,wmNews);
        }
        List<String> list2 = wmNewsDto.getImages();
        if (!list2.isEmpty()){
            // 1 主图引用
            saveRelation((short)1,list2,wmNews);
        }




    }

    private void saveRelation(short i, List<String> result,WmNews wmNews) {
        //     存储信息
        List<WmMaterial> list1 = materialService.lambdaQuery().select(WmMaterial::getId)
                .in(WmMaterial::getUrl, result)
                .list();
        List<WmNewsMaterial> idList = list1.stream().map(m -> {
                    WmNewsMaterial wm = new WmNewsMaterial();
                    wm.setMaterialId(m.getId());
                    wm.setNewsId(wmNews.getId());
                    wm.setType(i);
                    return wm;
                })
                .collect(Collectors.toList());

        materialNewService.saveBatch(idList);

    }

    /**
     * @param wmNews
     * 内容图片>=3  type=3
     * <3  type=1
     * 0  type=0
     * @return
     */
    private WmNews handImages(WmNews wmNews) {
        List<Map> list = JSONUtil.toList(JSONUtil.parseArray(wmNews.getContent()), Map.class);
        ArrayList<String> result = new ArrayList<>();
        for (Map map : list) {
            if (map.get("type").toString().equals("image")) {
                String pickerUrl = map.get("value").toString();
                result.add(pickerUrl);
            }
        }
        if (result.size() == 0) {
            wmNews.setType((short)0);
        } else if (result.size() >= 3) {
            wmNews.setType((short)3);
            wmNews.setImages(StrUtil.join(",",result));
        }else {
            wmNews.setType((short)1);
            wmNews.setImages(StrUtil.join(",",result));
        }
        return wmNews;
    }


}
